//
// Created by Administrator on 2019\11\1 0001.

#ifndef STEREO_UTILS_H
#define STEREO_UTILS_H


#define CV_CPU_HAS_SUPPORT_NEON 1
#include "opencv2/core/hal/intrin.hpp"

#include "stdlib.h"
#include <cmath>

#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>

#include <iostream>
#include <cmath>
#include <opencv2/opencv.hpp>
#include "opencv2/ximgproc/edge_filter.hpp"
#include "opencv2/ximgproc/disparity_filter.hpp"
#include "opencv2/ximgproc/weighted_median_filter.hpp"
#include <opencv2/xfeatures2d.hpp>


// switch to turn on or off UI
#define SHOW_WINDOWS 1


using namespace cv;
using namespace std;
using namespace cv::ximgproc;

namespace r3d_depth_image{

	void VisualizeOpticalFlow(
		cv::Mat & output,
		const std::vector<cv::Point2f> & src,
		const std::vector<cv::Point2f> & dst);

	void Erode_v3(
		cv::Mat & o_,
		const cv::Mat & i_,
		const cv::Mat & rgb,
		int r,
		uint8_t threshold
		);

	void Dilate_v3(
		cv::Mat & o_,
		const cv::Mat & i_,
		const cv::Mat & rgb,
		int r,
		uint8_t threshold
		);

	void SmoothDisparity(
		cv::Mat & o_,
		const cv::Mat & i_,
		const cv::Mat & edge,
		bool use_mask,
		int min_support);

	void SmoothDisparityWithDomains(
		cv::Mat & o_,
		const cv::Mat & i_,
		const cv::Mat & domains,
		int num_domains,
		const cv::Mat & mask);

	void GetFullEdges(
		cv::Mat & o_, 
		const cv::Mat & i_,
		int thres_selc, 
		int thres_conn);

	void FindConnectedDomain(
		cv::Mat & domain_map,
		std::vector<int> & counts,
		cv::Rect & visible_zone,
		const cv::Mat & edge);

	void VisualizeDomains(
		cv::Mat & rgb, 
		const cv::Mat & domains, 
		int num_domain);

	void ColorBasedFilter(
		cv::Mat & o_,
		const cv::Mat & i_,
		const cv::Mat & rgb,
		int r
		);

	class Erode_v3_fastest_class;

	void Erode_v3_fastest(
		cv::Mat & o_,
		const cv::Mat & i_,
		const cv::Mat & rgb,
		int r,
		int threads_num,
		uint8_t threshold = 255
		);

	class Dilate_v3_fastest_class;


	void Dilate_v3_fastest(
		cv::Mat & o_,
		const cv::Mat & i_,
		const cv::Mat & rgb,
		int r,
		int threads_num,
		uint8_t threshold = 255
		);

	void FillBlackBorder(cv::Mat & disp_pri, int std_max_disp, int win_size);

	void Histogram(cv::Mat & hist, const cv::Mat & depth, int hist_size);

	void VisualizeHistogram(cv::String title, cv::Mat & hist);

	// for static stereo rectification
	void StaticStereoRectify(
		const cv::Mat & M1,
		const cv::Mat & D1,
		const cv::Mat & M2,
		const cv::Mat & D2,
		const cv::Mat & R,
		const cv::Mat & T,
		const cv::Size & size,
		cv::Mat & map11,
		cv::Mat & map12,
		cv::Mat & map21,
		cv::Mat & map22,
		cv::Mat & imap1,
		cv::Mat & imap2,
		cv::Mat & Q);

	void GetRightPoint(std::vector<cv::Point2f> &rightVec,
		std::vector<cv::Point2f> &leftVec,
		std::vector<cv::Point2f> &rightVecOut,
		std::vector<cv::Point2f> &leftVecOut,
		std::vector<uchar> &status,
		float ratio);

	int RowAlign_grid(
		cv::Mat & im2_aligned, // rectified aux, gray
		const cv::Mat & im1, // main, rgb
		const cv::Mat & im2, // aux, gray
		int num_feat,
		int max_iter,
		float res_level,
		int num_worst,
		int margin_x,
		int margin_y,
		float & max_disp,
		float & min_disp,
		cv::Mat & row_align
		);

	void HistBasedFilter(cv::Mat & im_disp, float min_support, bool ignore_zero);

	void DilatedMedianBlur(
		cv::Mat & _out,
		const cv::Mat & _in,
		int radius,
		bool use_mask);

	void DilatedMedianBlurRGB(
		cv::Mat & _out,
		const cv::Mat & _in,
		int radius);

	void DumpImage(const cv::Mat & im_,
		const cv::String & path,
		const cv::String & postfix,
		const cv::String & uid);

	void Disparity2Depth(cv::Mat &disp, float & min_, float & max_);

	void Depth2Disparity(cv::Mat &depth, float min_, float max_);

	void ChangeSaturation(cv::Mat &in_out, int degree);

	void HistBasedPeakFilter_(cv::Mat & im_disp, float min_support, int min_disp);

	void FillBlackHoles_new(cv::Mat & io_, const cv::Mat & guide, bool dilation);

	void FillBlackHolesSmallRegion(cv::Mat & io_, const cv::Mat & guide, int iters);

	void FillBlackHolesSimple(cv::Mat & im_rgb, cv::Mat & depth);

	void removeWhiteEdge(cv::Mat & input);

	void removeTextureless(cv::Mat & disp, cv::Mat &guided);

	void removeSpot(cv::Mat &disp);

	void FillBlackHoles_iters(cv::Mat & io_, const cv::Mat & guide, int iters);

	void StringSplit(const string& s, vector<string>& tokens, const string& delimiters);

	std::string& StringTrim(std::string &s);

	void ChopCorners(cv::Mat & io_, int size);

	void CropBall(cv::Mat & io_, float ratio);

	void ShowImg(cv::String name, const cv::Mat & im);

	void WaitKey(int sec);
}

#endif //STEREO_UTILS_H


